/*
*MedianCutter.java
* Galen Marisco
*
*/
import java.util.*;

/* This Class is for determining the pixel values at which to split the grey-level
 * intensity of an image for colour quantization using the median cut algorithm. 
 * This class will return split markers for 1,2 and 3-bit schemes. Images must be
 * passed to the class as 2-d arrays of doubles(gray-levels).
 * */

public class MedianCutter{
	int[][] distribution;
	
	
	public MedianCutter(){
		distribution = new int[256][2];
		for(int i = 0; i < 256; i++){
			distribution[i][0] = i;
			distribution[i][1] = 0;
		}//end for
	}//end constructor
	
	public void populateDistribution(double[][][] image, int width, int height){
		for(int x = 0; x < width; x++){
			for(int y = 0; y < height; y++){
				distribution[ (int) image[x][y][0] ][1] += 1 ;
			}//end for
		}//end for
	}//end populateDistribution
	
	public void dumpDistribution(){
		for(int i = 0; i<256; i++){
			System.out.println(distribution[i][0] + " : " + distribution[i][1]);
		}//end for
	}//end dumpDistribution
	
	
	
	
	public int[] getMedian1bit(double[][][] image, int width, int height){
		System.out.println("Total Number of Pixels: " + width*height);
		int pixCount = width*height;
		int split[] = new int[7];
		int index = 0;
		int count = 0;
		populateDistribution(image, width, height);
		while(index < 256 && count < pixCount/2){
			count += distribution[index][1];
			index += 1;
		}//end while
		if(index >= 256){
			index = 250;
		}
		
		split[0] = index;
		for(int i = 1; i < 7; i++){
			split[i] = 0;
		}
		return split;
	}//end getMedian1bit
	

	public int[] getMedian2bit(double[][][] image, int width, int height){
		System.out.println("Total Number of Pixels: " + width*height);
		int split[] = new int[7];
		int pixCount = width*height;
		int index1, index2, index3;
		populateDistribution(image, width, height);
		int count = 0;
		index2 = 0;
		
		//center
		while(index2 < 256 && count <= pixCount/2){
			count += distribution[index2][1];
			index2 += 1;
		}//end while

		index1 = 0;
		count = 0;	
		//left
		while(index1 < index2 && count <= pixCount/4 ){
			count += distribution[index1][1];
			index1 += 1;
		}//end while
		

		
		index3 = index2;
		count = 0;
		//right
		while(index3 < 256 && count <= pixCount/4){
			count += distribution[index3][1];
			index3 += 1;
		}//end while
		
		//line drawings
		if(index2 >= 256){
			index1 = 100;
			index2 = 200;
			index3 = 250;
		}
		//really white images
		if(index3 >= 256){
			index3 = 255;
		}


		split[0]=index1;
		split[1]=index2;
		split[2]=index3;
		for(int i = 3; i < 7; i++){
			split[i] = 0;
		}
		
		return split;
	}//end getMedian2bit
	
	
	//No recursion in my house!
	public int[] getMedian3bit(double[][][] image, int width, int height){
		System.out.println("Total Number of Pixels: " + width*height);
		int split[] = new int[7];
		int pixCount = width*height;
		int index1, index2, index3, index4, index5, index6, index7;
		populateDistribution(image, width, height);
		int count = 0;
		
		index4 = 0;
		//center
		while(index4 < 256 && count <= pixCount/2){
			count += distribution[index4][1];
			index4 += 1;
		}//end while

		index2 = 0;
		count = 0;	
		//left
		while(index2 < index4 && count <= pixCount/4 ){
			count += distribution[index2][1];
			index2 += 1;
		}//end while
		
		index6 = index4;
		count = 0;
		//right
		while(index6 < 256 && count <= pixCount/4){
			count += distribution[index6][1];
			index6 += 1;
		}//end while

		index1 = 0;
		count = 0;
		while(index1 < index2 && count <= pixCount/8){
			count += distribution[index1][1];
			index1 += 1;	
		}
		
		index3 = index2;
		count = 0;
		while(index3 < index4 && count <= pixCount/8){
			count += distribution[index3][1];
			index3 += 1;
		}
		
		index5 = index4;
		count = 0;
		while(index5 < index6 && count <= pixCount/8){
			count += distribution[index5][1];
			index5 += 1;
		}

		index7 = index6;
		count = 0;
		while(index7 < 256 && count <= pixCount/8){
			count += distribution[index7][1];
			index7 += 1;
		}
		if(index4 >= 256){
			index1 = 50;
			index2 = 100;
			index3 = 150;
			index4 = 200;
			index5 = 220;
			index6 = 240;
			index7 = 250;
		}
		if(index5 >= 256){
			index5 = 255;
		}
		if(index6 >= 256){
			index6 = 255;
		}
		if(index7 >= 256){
			index7 = 255;
		}
		
		split[0]=index1;
		split[1]=index2;
		split[2]=index3;
		split[3]=index4;
		split[4]=index5;
		split[5]=index6;
		split[6]=index7;
		return split;
	}///end getMedian3bit
	
	
	//returns the median at which to split our grey level intensity at for
	//1-bit images

	
}//end class